/*
 * hero.cpp
 *
 *  Created on: 26.12.2012
 *      Author: Michael
 */
#include "hero.h"
#include <stdio.h>

void Hero::escape(char maze[10][10], bool showProgress) {
	doEscape(_start, maze, showProgress);
}

bool Hero::doEscape(Position curr, char maze[10][10], bool showProgress) {
	// mark current position
	maze[curr.x][curr.y] = _signs.breadcrump;

	// output
	if (showProgress) {
		print(maze);
	}

	bool exitFound = false;

	// exit condition
	if (maze[curr.x][curr.y] == _signs.exit) {
		return true;
	}

	// move left if possible
	Position left = getLeft(curr);
	if (!exitFound && maze[left.x][left.y] != _signs.wall
			&& maze[left.x][left.y] != _signs.breadcrump) {
		exitFound = doEscape(left, maze, showProgress);
	}

	// move straight ahead if possible
	Position front = getFront(curr);
	if (!exitFound && maze[front.x][front.y] != _signs.wall
			&& maze[front.x][front.y] != _signs.breadcrump) {
		exitFound = doEscape(front, maze, showProgress);
	}

	// move right if possible
	Position right = getRight(curr);
	if (!exitFound && maze[right.x][right.y] != _signs.wall
			&& maze[right.x][right.y] != _signs.breadcrump) {
		exitFound = doEscape(right, maze, showProgress);
	}

	// move backwards if possible
	Position back = getBack(curr);
	if (!exitFound && maze[back.x][back.y] != _signs.wall
			&& maze[back.x][back.y] != _signs.breadcrump) {
		exitFound = doEscape(back, maze, showProgress);
	}

	return false;
}

Position Hero::getLeft(Position curr) {
	switch (curr.direction) {
	case NORTH:
		curr.y--;
		curr.direction = WEST;
		break;
	case EAST:
		curr.x--;
		curr.direction = NORTH;
		break;
	case SOUTH:
		curr.y++;
		curr.direction = EAST;
		break;
	case WEST:
		curr.x++;
		curr.direction = SOUTH;
		break;
	}
	return curr;
}

Position Hero::getRight(Position curr) {
	switch (curr.direction) {
	case NORTH:
		curr.y++;
		curr.direction = EAST;
		break;
	case EAST:
		curr.x++;
		curr.direction = SOUTH;
		break;
	case SOUTH:
		curr.y--;
		curr.direction = WEST;
		break;
	case WEST:
		curr.x--;
		curr.direction = NORTH;
		break;
	}
	return curr;
}

Position Hero::getFront(Position curr) {
	switch (curr.direction) {
	case NORTH:
		curr.x--;
		break;
	case EAST:
		curr.y++;
		break;
	case SOUTH:
		curr.x++;
		break;
	case WEST:
		curr.y--;
		break;
	}
	return curr;
}

Position Hero::getBack(Position curr) {
	switch (curr.direction) {
	case NORTH:
		curr.x++;
		curr.direction = SOUTH;
		break;
	case EAST:
		curr.y--;
		curr.direction = WEST;
		break;
	case SOUTH:
		curr.x--;
		curr.direction = NORTH;
		break;
	case WEST:
		curr.y++;
		curr.direction = EAST;
		break;
	}
	return curr;
}

void Hero::print(char maze[10][10]) {
	for (int i = 0; i < DIMENSION; ++i) {
		for (int j = 0; j < DIMENSION; ++j) {
			printf("%c ", maze[i][j]);
		}
		printf("\n");
	}
	printf("\n");
}
